﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dycox.ComponentModel;

namespace Dycox.Workflows
{
    public class ConditionTestArguments : Dycox.Utils.IContainerProvider
    {
        internal ConditionTestArguments(IWorkflowComponent component, StageContract contract, Stage stage, IReflectionRoot reflectingObject)
        {
            if (stage == null)
                throw new ArgumentNullException("stgae");

            _component = component;
            _contract = contract;
            _stage = stage;
            _reflectingObject = reflectingObject;
        }

        private IWorkflowComponent _component;

        public IWorkflowComponent Component
        {
            get { return _component; }
        }

        private StageContract _contract;

        public StageContract UseState
        {
            get { return _contract; }
        }

        private Stage _stage;

        public Stage Stage
        {
            get { return _stage; }
        }

        private IReflectionRoot _reflectingObject;

        public IReflectionRoot ReflectionObject
        {
            get { return _reflectingObject; }
        }

        public WFStep GetStep()
        {
            return _component as WFStep;
        }

        public WFThread GetThread()
        {
            WFStep step = GetStep();
            if (step != null)
                return step.Thread;

            if (_component is WFThread)
                return (WFThread)_component;

            return null;
        }

        public WFProcess GetProcess()
        {
            WFThread thread = GetThread();

            if (thread == null)
                return _component as WFProcess;
            else
                return thread.Process;
        }

        object Utils.IContainerProvider.GetContainer(string containerName)
        {
            if (string.IsNullOrEmpty(containerName))
                return ((Utils.IContainerProvider)this).DefaultContainer;

            object container;


            if (containerName[0] == '#')
            {
                IWorkflowComponent component = this.Component;
                containerName = containerName.Substring(1);

                if (component != null && !(component is WFProcess))
                {
                    Workflow wf = _stage.Workflow;
                    WFStep step = GetStep();

                    if (step == null)
                        step = GetThread().ActiveStep;

                    if (step != null)
                    {
                        step = wf.Control.GetNearestCompletedStep(step, containerName);
                        container = step.GetUserState(wf.Stages[step]);
                    }
                    else
                        container = null;

                }
                else
                    container = null;
            }
            else
            {
                switch (containerName.ToLower())
                {
                    case "userstate":
                        container = UseState;
                        break;
                    case "step":
                        container = GetStep();
                        break;
                    case "thread":
                        container = GetThread();
                        break;
                    case "process":
                        container = GetProcess();
                        break;
                    case "app":
                        container = ReflectionObject;
                        break;
                    default:
                        throw new NotSupportedException("Context type " + containerName + " is not supported.");
                }
            }



            return container;


        }

        object Utils.IContainerProvider.DefaultContainer
        {
            get { return this.UseState; }
        }
    }
}
